package com.example.user.controller;

import com.example.model.pojo.User;
import com.example.model.utils.UserHolder;
import com.example.model.common.R;
import com.example.model.pojo.dto.ChangePasswordDTO;
import com.example.model.pojo.dto.LoginDTO;
import com.example.model.pojo.vo.LoginVO;
import com.example.model.pojo.vo.UserInfoVO;
import com.example.user.service.UserService;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

/**
 * 用户控制器
 */
@RestController
@RequestMapping("/user")
@Tag(name = "用户管理", description = "提供用户登录、注销、修改密码、获取用户信息等接口")
public class UserController {

    @Autowired
    private UserService userService;

    /**
     * 用户登录接口
     * @param loginDTO 登录信息
     * @return 登录结果，包含token和用户信息
     */
    @PostMapping("/login")
    @Operation(summary = "用户登录", description = "用户登录接口，支持学号/教师工资号登录，登录成功返回JWT令牌和用户信息")
    public R<LoginVO> login(@RequestBody LoginDTO loginDTO) {
        try {
            // 调用服务层进行登录
            LoginVO loginVO = userService.login(loginDTO);
            // 返回登录成功响应
            return R.loginSuccess(loginVO);
        } catch (RuntimeException e) {
            // 处理业务异常
            return R.fail(400, e.getMessage());
        } catch (Exception e) {
            // 处理其他异常
            return R.fail(500, "登录失败：" + e.getMessage());
        }
    }

    /**
     * 用户注销接口
     * @return 注销结果
     */
    @PostMapping("/logout")
    @Operation(summary = "用户注销", description = "用户注销接口，清除用户登录状态")
    public R<Void> logout() {
        try {
            // 从线程本地存储中获取当前用户
            User currentUser = UserHolder.get();
            if (currentUser == null) {
                return R.fail(401, "用户未登录");
            }
            
            // 调用服务层进行注销
            userService.logout(currentUser.getId());
            // 返回注销成功响应
            return R.logoutSuccess();
        } catch (RuntimeException e) {
            // 处理业务异常
            return R.fail(400, e.getMessage());
        } catch (Exception e) {
            // 处理其他异常
            return R.fail(500, "注销失败：" + e.getMessage());
        }
    }

    /**
     * 修改密码接口
     * @param changePasswordDTO 密码修改信息
     * @return 修改结果
     */
    @PostMapping("/change-password")
    @Operation(summary = "修改密码", description = "用户修改密码接口，需要提供原密码和新密码")
    public R<Void> changePassword(@RequestBody ChangePasswordDTO changePasswordDTO) {
        try {
            // 从线程本地存储中获取当前用户
            User currentUser = UserHolder.get();
            if (currentUser == null) {
                return R.fail(401, "用户未登录");
            }
            
            // 调用服务层修改密码
            boolean result = userService.changePassword(currentUser.getId(), changePasswordDTO);
            if (result) {
                // 返回修改成功响应
                return R.passwordChangeSuccess();
            } else {
                return R.fail(400, "密码修改失败");
            }
        } catch (RuntimeException e) {
            if ("原密码错误".equals(e.getMessage())) {
                // 原密码错误的特殊处理
                return R.oldPasswordError();
            }
            // 处理其他业务异常
            return R.fail(400, e.getMessage());
        } catch (Exception e) {
            // 处理其他异常
            return R.fail(500, "修改密码失败：" + e.getMessage());
        }
    }

    /**
     * 获取用户信息接口
     * @return 用户信息
     */
    @GetMapping("/info")
    @Operation(summary = "获取用户信息", description = "获取当前登录用户的基本信息")
    public R<UserInfoVO> getUserInfo() {
        try {
            // 从线程本地存储中获取当前用户
            User currentUser = UserHolder.get();
            if (currentUser == null) {
                return R.fail(401, "用户未登录");
            }
            
            // 调用服务层获取用户信息
            UserInfoVO userInfoVO = userService.getUserInfo(currentUser.getId());
            // 返回用户信息
            return R.success(userInfoVO);
        } catch (RuntimeException e) {
            // 处理业务异常
            return R.fail(400, e.getMessage());
        } catch (Exception e) {
            // 处理其他异常
            return R.fail(500, "获取用户信息失败：" + e.getMessage());
        }
    }
}